package szoftlab4sunak;

import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;

//A BattleDevice egy tipusa, Cell-re rakva lovi a hatosugaraba kerulo Enemy-ket
public class Tower implements BattleDevice {
	
    Stone stone; //a belerakott ko tarolasara szolgag
    private char stoneType;
    int Range; // a Tower hatotavolsagat tarolja, Cell-ben kell ertelmezni 
    int Damage; // a Tower sebzeset tarolja
    int Speed; // Tower lovesi sebessege
    ArrayList<Cell> targetCells; // azon Cell-eket tarolja, amelyek beleesnek a hatotavolsagaba
    ArrayList<Enemy> targets; // a torony latotavolsagan beluli ellenfeleket tarolo lista
    Enemy target; // az aktualisan sebzesre kivalasztott ellenfelet tarolo attributum
    int id; // a torony egyedi ID-ja
    boolean cut; // ezen attributum segitsegevel allithato be, hogy a torony lovedeke szetvagja-e az ellenfelet
    boolean isFog; // ezen attributum segitsegevel allithato be, hogy a tornyon van-e kod
    Cell currentCell; // az aktualis cella, amin a torony talalhato
	ArrayList<String> op; // a kiirashoz szukseges lista
	private int Posx; //a tenyleges pozicio x koordinataja
	private int Posyy; //a tenyleges pozicio y koordinataja
	private Init init; //init objektum tarolasa
	public Color col; //a Tower szinenek tarolasa
	int speedTemp; //sebesseg kezeleshez segedvaltozo
	ArrayList<Cell> targetCells2; //ellenfelek kivalasztasahoz segedvaltozo
    
	//visszaadja az tenyleges X koordinatat (bal sarka a Cell-nek)
	public int getPosx() {
		return Posx;
	}
	
	//beallitja a tenyleges X koordinatat (bal sarka a Cell-nek)
	public void setPosx(int posx) {
		Posx = posx;
	}
	
	//visszaadja az tenyleges Y koordinatat (bal sarka a Cell-nek)
	public int getPosyy() {
		return Posyy;
	}

	//beallitja az tenyleges Y koordinatat (bal sarka a Cell-nek)
	public void setPosyy(int posyy) {
		Posyy = posyy;
	}

	// az osztaly alapertelmezett konstruktora
	public Tower() {
		// beallitjuk a mukodeshez szukseges parametereket
		targets = new ArrayList<Enemy>();
		cut = false;
		isFog = false;
		Range = 1;
		Speed = 1;
		Damage = 1;
		targetCells = new ArrayList<Cell>();
		targetCells2 = new ArrayList<Cell>();
		targetCells.add(currentCell);
	}
	
	// az osztaly parameteres konstruktora
	public Tower(int id, Cell currentCell, Init init, ArrayList<String> op) {
		// beallitja a mukodeshez szukseges parametereket
		this.op=op;
		this.init = init;
		targets = new ArrayList<Enemy>();
		targetCells = new ArrayList<Cell>();
		targetCells2 = new ArrayList<Cell>();
		this.id = id;
		cut = false;
		isFog = false;
		Range = 1;
		Speed = 2;
		Damage = 1;
		speedTemp = Speed;
		this.currentCell = currentCell;

		// vegignezi a latotavolsagan beluli cellakat
		Cell neighbours[] = currentCell.getNeighbours();
		for(Cell c: neighbours)
			targetCells.add(c);
		targetCells2.addAll(targetCells);
		
		//beallitja a tenyleges poziciot
		this.Posx = currentCell.getPosX();
		this.Posyy = currentCell.getPosY()+100;
	}
	
    //a parameterben megadott Stone-t eltarolja a Stone attributumaban
    public void putStone(Stone stone, char type, int stoneid) {
	    	this.stone = stone;
	    	// ha "range" tipusu kovet adunk at parameterkent
	    	if(type == 'r') {
	    		// megnoveli a hatotavolsagat
	    		Range ++;
	    		this.stoneType = type;
	    		setPlusCells();
	    	}
	    	// ha "damage" tipusu kovet adunk at parameterkent
	    	else if(type == 'd') {
	    		// megnoveli a sebzeset
	    		Damage ++;
	    		this.stoneType = type;
	    	}
	    	// ha "speed" tipusu kovet adunk at parameterkent
	    	else if (type == 's'){
	    		//megnoveli a lovesi sebesseget
	    		this.stoneType = type;
	    		Speed--;
	    	}
    	
    }
    
    //visszaadja, milyen tipusu stone van rajta
    public char getStoneType(){
    	return this.stoneType;
    }
    
    //a Tower Tick fuggvenye, amely segitsegevel a Tower lo
    public void Tick() {
    	targets.clear();
    	target = null;
    	// ha nincs kod
    	if(!isFog) {
	    	//veletlenszeru utkivalasztashoz
	    	Random random = new Random();
	    	int rand = random.nextInt(9);
	    	if(rand == 8)
	    		cut = true;
	    	// ha a toronyra nem ereszkedett kod
	    	if(speedTemp == 0) {
	    		// vegigmegy a latotavolsagan belul eso cellakon
		    	for(Cell tc : targetCells) {
		    		if(tc != null)
		    			// ha az adott cellan van ellenseg
			    		if(!tc.haveEnemy().isEmpty()) {
			    			// lekeri az adott cellarol az ellensegeket
			    			HashMap<Integer, Enemy> enemies = tc.haveEnemy();
			    			// a sajat, latotavolsagan belul eso ellenfeleket egy kulon tarolaba helyezi
			    			Iterator iter = enemies.keySet().iterator();
			    	    	while(iter.hasNext()) {
			    	    	    Integer key = (Integer)iter.next();
			    	    	    Enemy ve = enemies.get(key);
			    	    	    if(ve!=null)
			    	    	    	targets.add(ve);
			    	    	}
			    		}
		    	}
		    	// kivalaszt egy ellenfelet, amelyet majd sebezni fog
		    	target = setTarget();
		    		// ha sebzo lovedeket lo a torony
		    		if(!cut && target != null) {
		    			// meglovi az ellenseget
		    			target.Shoot(this);
		    			int amount = Damage();
		    			// csokkenti az ellenseg eleterejet a parameterkent atadott mennyiseggel
		    			target.Decrease(amount);
		    		}
		    		// ha vago lovedeket lo a torony
		    		else if(target != null) {
		    			// elvagja az ellenfelet
		    			target.cutYourSelf();
		    	}
		    //megint varnia kell, hogy lohessen
	    	speedTemp = Speed;    	
	    	}
	    	else
	    		speedTemp--;
    	}
    	//ha kod volt, akkor leszedi
    	if(isFog)
    		isFog = false;
    	cut = false;
    	//kiiratahoz kell
    	if(target != null) {
    		App.datas[init.map.rowCounter] = init.map.sumCounter + ". A(z) " + target.getID() + " ID-u Enemy sebzodott, maradek elete: " + target.getHP() + "\n";
    		init.map.sumCounter++;
    		init.map.rowCounter++;
    		if(init.map.rowCounter == 4)
    			init.map.rowCounter = 1;
    	}
    }
    
    //A sebzest vegzo fuggveny, kiszamolja hogy mennyi eleterot kell sebeznie
    public int Damage() {
    	return Damage*20;
    }
    
    //Ez a fuggveny adja meg, hogy a Tower-en van-e mar Stone
    public boolean haveStone() {
    	if (this.stone == null){
    		return false;
    	}
    	else{
    		return true;
    	}
    }
    
    // a torony parametereit allito fuggveny
    public void setParams(String bulettype, boolean fog) {
    	// ha a lovedek tipusa vago
    	if(bulettype.equals("cut"))
    		cut = true;
    	else
    		cut = false;
    	// ha kod ereszkedik a toronyra
    	if(fog)
    		isFog = true;
    	else
    		isFog = false;
    }
    
    // beallitja az aktualis ellenfelet, amelyre majd lovest ad le
    public Enemy setTarget() {
    	if(targets.isEmpty())
    		return null;
    	else
    	{	
    		return targets.get(0);
    	}
    }
    
    //kod leszall
	@Override
	public void FogOn() {
		this.isFog = true;
		
	}
	
	//target cell-ek beallitasahoz kell
	public void setPlusCells() {
		if(!targetCells2.isEmpty()) {
			for(Cell c: targetCells2) {
				if(c != null) {
					Cell newNeighbours[] = c.getNeighbours();
					for(Cell cell: newNeighbours) {
						if(!targetCells.contains(cell))
							targetCells.add(cell);
					}
				}
			}
		}
	}

}